<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.id">
      <dt>{{item.name}}</dt>
      <dd>
        <template v-for="val in item.values" :key="val.name">
        <img  @click="clickSpecs(item,val)" :class="{selected:val.selected,disabled: val.disabled}" :src="val.picture" :title="val.name" alt="" v-if="val.picture">
        <span @click="clickSpecs(item,val)" :class="{selected:val.selected,disabled: val.disabled}" v-else>{{val.name}}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import bwPowerSet from '@/vender/power-set'
import { watch } from 'vue'
// import { useRoute } from 'vue-router'
// import { useRoute } from 'vue-router'
// 通过幂算法处理数据  传入一个数组
// const res = bwPowerSet(['中国', '10cm', '蓝色'])
// const arr = []
// res.forEach(item => {
//   // 通过字符串的拼接  拼接到一个数组上
//   arr.push(item.join('*'))
// })
// console.log(arr)
// 准备字典
const spliter = '★'
const getPathMap = (skus) => {
  const pathMap = {}
  skus.forEach(sku => {
    //   定义一个空对象
    //   如果有库存
    if (sku.inventory) {
    //   console.log(sku)
      const specs = bwPowerSet(sku.specs.map(item => item.valueName))
      //   console.log(specs)
      specs.forEach(item => {
        //   将数组拼接成一个字符串
        const key = item.join(spliter)
        // console.log(key)
        // 有没有key值
        if (!pathMap[key]) {
          // 初始化一个数组，并放入第一个 skuid
          pathMap[key] = [sku.id]
        } else {
          // 已经存在，追加新的 skuid 进去即可
          pathMap[key].push(sku.id)
        }
      })
    }
  })
  return pathMap
}

// 得到当前选中规格的集合，用于模拟下一次动作
const getSelectedArr = (specs) => {
//   console.log(specs)
  const arr = []
  specs.forEach(spec => {
    //   所有选中状态
    const obj = spec.values.find(item => item.selected)
    // console.log(obj)
    // 有这个对象，才追加名字，没有就是undefined
    arr.push(obj ? obj.name : undefined)
  })
  return arr
}

// 更新按钮的禁用状态

const updateDisabledStatus = (specs, pathMap) => {
  // console.log(pathMap)
  //   console.log(specs)
  //   遍历所有规格
  specs.forEach((spec, index) => {
    //   获取所有选中的规格集合
    const selectedArr = getSelectedArr(specs)
    // console.log(selectedArr, spec)
    // 🔔 根据当前选中，模拟用户的下一次选中
    spec.values.forEach(item => {
    //   console.log(selectedArr[index])
      // 已经选中的按钮不用判断
      if (item.selected) return
      // 模拟其他未选中的值
      selectedArr[index] = item.name
      // 过滤掉无效值并处理成字符串，用于查字典
      const key = selectedArr.filter(v => v !== undefined).join(spliter)
      // console.log(key)
      // console.log(pathMap)
      // 查找字典中是否存在，不存在就处理成禁用状态
      item.disabled = !pathMap[key]
    })
  })
}

// 根据skuId默认显示显示
const initSelectedStatus = (skuId, goods) => {
  //   console.log(skuId, goods)
  // 根据 skuId 查询到需要实现选中的规格对象
  const sku = goods.skus.find(item => item.id === skuId)
  //   console.log(sku)
  if (sku) {
    // 遍历商品规格数组
    goods.specs.forEach((spec, index) => {
    //   console.log(spec, index)
    // 拿到默认选中的值 // 根据下标获取到规格文字
      const value = sku.specs[index].valueName
      //   console.log(value)
      spec.values.forEach(item => {
        //   默认显示选中状态 默认skuid名字对的上就选中 // 添加选中状态
        item.selected = item.name === value
      })
    })
  }
}

export default {
  name: 'GoodsSku',
  props: {
    goods: {
      type: Object,
      default: () => ({})
    },
    // 购物车页面需要根据 skuId 实现默认规格选择
    skuId: {
      type: String,
      default: ''
    }
  },
  setup (props, { emit }) {
    // const route = useRoute()
    // 字典
    // console.log(props.goods)
    // let pathMap
    let pathMap = getPathMap(props.goods.skus)
    // console.log(pathMap)
    watch(props, async () => {
      // console.log(1)
      // console.log(props.goods)
      // 字典没更新
      pathMap = await getPathMap(props.goods.skus)
    })
    initSelectedStatus(props.skuId, props.goods)
    // 进来更新按钮转态
    updateDisabledStatus(props.goods.specs, pathMap)
    // 如果有skuId，应该页面默认显示  // 根据传入的skuId默认选中规格按钮

    // 点击规格实现选中高亮效果
    const clickSpecs = (item, val) => {
      // console.log(item, val)
      // 如果是禁用状态不作为
      if (val.disabled) return
      // console.log(1)
      // 1. 选中与取消选中逻辑
      if (!val.selected) {
        //   全部设置为false
        item.values.forEach(item2 => { item2.selected = false })
        // 在单独设置为true ，排他
        val.selected = true

        // 实现选中的时候获取选中的数组
        const res = getSelectedArr(props.goods.specs)
        console.log(res)
        // 如果没有全部选择应该提示
        if (res.includes(undefined)) {
          console.log('还没有选完整')
          emit('change', {})
        } else {
          console.log(2, '规格选择完整', res)
          // 根据完整规格获取到skuid
          const key = res.join(spliter)
          // console.log(key)
          // 拿到skuid
          const [skuId] = pathMap[key]
          // console.log(skuId)
          // 根据skuid查找商品信息(价格,旧价格,库存,规格文本)
          const obj = props.goods.skus.find(item => item.id === skuId)
          // console.log(obj)
          const data = {
            skuId: obj.id,
            inventory: obj.inventory,
            oldPrice: obj.oldPrice,
            price: obj.price,
            attrsText: obj.specs.map(({ name, valueName }) => `${name}: ${valueName}`).join(' ')
          }
          // console.log(data)
          emit('change', data)
        }
      } else {
        val.selected = false
        emit('change', {})
      }
      //   更新组件
      updateDisabledStatus(props.goods.specs, pathMap)
    }
    return { clickSpecs, pathMap }
  }
}
</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
   margin-bottom: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
